<script setup>
import { exportExcel } from '@/utils/exportExcel'
import { ElNotification } from 'element-plus'
import moment from 'moment'
import { computed, onMounted, watch } from 'vue'

const tableRef = ref(null)
const route = useRoute()
const total = computed(() => {
  return props.total ? props.total : props.data.length
})

const maxHeight = ref(0)

const exportName = computed(() => `${route.meta.title}` || '')

const tableClass = computed(() => {
  return { 'el-table-scrollbar': props.scrollbar }
})

const props = defineProps({
  data: {
    required: true,
    type: Array,
    default: () => []
  },
  tableColumn: {
    required: true,
    type: Array,
    default: () => []
  },
  showStripe: {
    type: Boolean,
    default: true
  },
  showBorder: {
    type: Boolean,
    default: true
  },
  showSummary: {
    type: Boolean,
    default: false
  },
  scrollbar: {
    type: Boolean,
    default: true
  },
  pageSize: {
    type: Number,
    default: 20
  },
  total: {
    type: Number
  },
  remote: {
    type: Boolean,
    default: false
  },
  showPagination: {
    type: Boolean,
    default: true
  },
  disabled: {
    type: Boolean,
    default: false
  },
  loading: {
    type: Boolean,
    default: false
  },
  loadingText: {
    type: String,
    default: '加载中'
  }
})

const page = ref({ pageSize: props.pageSize || 20, pageCurrent: 1 })

const emit = defineEmits([
  'selection-change',
  'row-dblclick',
  'filter-change',
  'sizeChange',
  'currentChange'
])

const tableData = computed(() => {
  const formatData = props.data.map((item, index) => {
    item.index = index
    return item
  })

  return props.remote || !props.showPagination
    ? formatData
    : formatData.slice(
        (page.value.pageCurrent - 1) * page.value.pageSize,
        page.value.pageSize * page.value.pageCurrent
      )
})

const tableColumn = computed(() => {
  const formatTableColumn = props.tableColumn.map(item => {
    item.showColumn = Object.getOwnPropertyNames(item).includes('showColumn')
      ? item.showColumn
      : true

    return item
  })

  return formatTableColumn
})

// 导出excel的字段，用于处理多层级表头的信息
const exportFields = computed(() => {
  return props.tableColumn.reduce((curr, prev) => {
    if (prev.type && prev.type === 'group' && prev.children.length > 0) {
      prev.children.forEach(item => {
        curr.push({ label: `${prev.label}-${item.label}`, key: item.prop })
      })
    } else {
      curr.push({ label: prev.label, key: prev.prop })
    }

    return curr
  }, [])
})

const exportToExcel = params => {
  const name = params && params.name ? params.name : exportName.value
  const time = moment().format('YYYY-MM-DD HH:mm:ss')
  try {
    exportExcel(props['data'], `${name}-${time}`, exportFields.value)
    ElNotification.success('导出成功')
  } catch (error) {
    ElNotification.error('导出失败')
  }
}

onMounted(() => {
  setTimeout(() => {
    const el = document.querySelector('.layout-main')
    maxHeight.value = el.clientHeight - 160
  }, 300)
})
defineExpose({ exportToExcel, tableRef })
</script>

<template>
  <div v-if="$slots.tools && !$props.disabled" class="ps_table_tools">
    <slot name="tools"></slot>
  </div>
  <el-table
    ref="tableRef"
    v-loading="$props.loading"
    :element-loading-text="$props.loadingText"
     :header-cell-style="{ 'text-align': 'center' }"
    v-bind="$attrs"
    :data="tableData"
    :stripe="$props.showStripe"
    :border="$props.showBorder"
    :show-summary="$props.showSummary"
    :scrollbar-always-on="$props.scrollbar"
    @selection-change="$emit('selection-change', $event)"
    @row-dblclick="$emit('row-dblclick', $event)"
    @filter-change="$emit('filter-change', $event)"
    :class="tableClass"
    class="ps_table"
   
  >
    <!-- 表身左侧的起始插槽，通常用于表单勾选 -->
    <template v-if="$slots.header">
      <slot name="header"></slot>
    </template>

    <el-table-column align="center" label="行" prop="index" width="60">
      <template #default="scope">
        {{ scope.row.index + 1 }}
      </template>
    </el-table-column>

    <template v-for="(item, index) in tableColumn" :key="`${item.prop}-${index}`">
      <!-- 控制列的显示 -->
      <el-table-column
        v-if="item.showColumn"
        :align="item.align || 'center'"
        :width="item.width"
        :minWidth="item.minWidth"
        :prop="item.prop"
        :label="item.label"
        :filters="item.filters"
        :filter-multiple="item.filterMultiple"
        :column-key="item.columnKey"
        :fixed="item.fixed"
        :sortable="item.sortable"
        show-overflow-tooltip
      >
        <template></template>

        <!-- 当存在tooltip时，显示tooltip -->
        <template #header>
          <template v-if="item.tooltip">
            <el-tooltip :content="item.tooltip" placement="top">
              <span :class="{ 'is-required': item.required }">{{ item.label }}</span>
            </el-tooltip>
          </template>

          <template v-else>
            <span :class="{ 'is-required': item.required }">{{ item.label }}</span>
          </template>
        </template>

        <template
          #default="scope"
          v-if="item.type && item.type === 'group' && item.children.length > 0"
        >
          <el-table-column
            v-for="sub in item.children"
            :key="sub.prop"
            :align="sub.align || 'center'"
            :width="sub.width"
            :minWidth="sub.minWidth"
            :prop="sub.prop"
            :label="sub.label"
            :filters="sub.filters"
            :filter-multiple="sub.filterMultiple"
            :column-key="sub.columnKey"
            :fixed="sub.fixed"
            show-overflow-tooltip
          >
            <template #header v-if="item.tooltip">
              <el-tooltip :content="item.tooltip" placement="top">
                <span>{{ item.label }}</span>
              </el-tooltip>
            </template>

            <template #default="scope">
              <component v-if="typeof sub.render === 'function'" :is="sub.render(scope.row)" />
              <span v-else-if="sub.formatter" v-html="sub.formatter(scope.row)"></span>
              <span v-else>{{ scope.row[sub.prop] }}</span>
            </template>
          </el-table-column>
        </template>

        <template v-else #default="scope">
          <!-- 禁用时，不显示render -->
          <template v-if="$props.disabled">
            <!-- 禁用时，如果有relieve，则显示render -->
            <component
              v-if="typeof item.render === 'function' && item.relieve"
              :is="item.render(scope.row)"
            />
            <span v-else-if="item.formatter" v-html="item.formatter(scope.row)"></span>
            <span v-else>{{ scope.row[item.prop] }}</span>
          </template>
          <component v-else-if="typeof item.render === 'function'" :is="item.render(scope.row)" />
          <span v-else-if="item.formatter" v-html="item.formatter(scope.row)"></span>
          <span v-else>{{ scope.row[item.prop] }}</span>
        </template>
      </el-table-column>
    </template>

    <!-- 表身结尾插槽，通常是用于展示tag信息以及单行的操作 -->
    <template v-if="$slots.footer && !$props.disabled">
      <slot name="footer"></slot>
    </template>
  </el-table>

  <el-pagination
    v-if="$props.showPagination"
    class="ps_pagination"
    v-model:current-page="page.pageCurrent"
    v-model:page-size="page.pageSize"
    :page-sizes="[10, 20, 30, 40, 50, 100, 200]"
    layout="prev, pager, next,total,sizes"
    @size-change="$emit('sizeChange', $event)"
    @current-change="$emit('currentChange', $event)"
    :total="total"
    background
  />
</template>

<style scoped lang="scss">
$scrollLineHeight: 0.8rem;

.el-table {
  &-scrollbar {
    :deep(.el-scrollbar) {
      overflow: unset;
    }

    :deep(.el-table__body-wrapper) {
      padding-bottom: $scrollLineHeight;
    }

    :deep(.el-scrollbar__bar) {
      bottom: -(($scrollLineHeight) - $scrollLineHeight * 0.2);
    }
  }
}
</style>
